<template>
    <div
        class="base-tooltip__trigger"
        @mouseover="overTrigger"
        ref="trigger"
        v-bind="$attrs"
    >
        <slot></slot>
    </div>
    <Teleport to="body" v-if="visible && !disabled">
        <div
            class="base-tooltip__body"
            :style="`top: ${bodyPosition.y}px; left: ${bodyPosition.x}px`"
            ref="tipBody"
            @mouseleave="onLeavedTrigger"
        >
            <slot name="body">
                {{ content }}
            </slot>
        </div>
    </Teleport>
</template>
<script setup>
const props = defineProps({
    content: String,
    disabled: Boolean,
});
const trigger = ref(null);
const tipBody = ref(null);
const visible = ref(false);
const bodyPosition = ref({
    x: -999,
    y: 0,
});
function overTrigger(event) {
    if (props.disabled) return;
    visible.value = true;
    trigger.value.addEventListener("mousemove", onMovedTrigger);
    trigger.value.addEventListener("mouseleave", onLeavedTrigger);

    requestAnimationFrame(() => {
        if (!tipBody.value) return;
        tipBody.value.classList.add("base-tooltip__body--active");
    });
}

function onMovedTrigger(event) {
    if (props.disabled) return;
    const { clientX, clientY } = event;
    requestAnimationFrame(() => {
        if (!tipBody.value) return;
        const { offsetHeight, offsetWidth } = tipBody.value;
        const { x, y } = getPosition(
            clientX,
            clientY,
            offsetHeight,
            offsetWidth
        );
        bodyPosition.value = {
            x,
            y,
        };
    });
}
function onLeavedTrigger() {
    if (props.disabled) return;
    if (!tipBody.value) return;
    tipBody.value.classList.remove("base-tooltip__body--active");
    trigger.value.removeEventListener("mousemove", onMovedTrigger);
    trigger.value.removeEventListener("mouseleave", onLeavedTrigger);
}
function getPosition(clientX, clientY, height, width) {
    const { clientWidth, clientHeight } = document.body;
    const offset = 20;
    let x = clientX + offset,
        y = clientY + offset;
    if (clientX + offset + width > clientWidth) {
        x = clientX - offset - width;
    }
    if (clientY + offset + height > clientHeight) {
        y = clientY - offset - height;
    }
    return {
        x,
        y,
    };
}
</script>
<style scoped>
.base-tooltip__body {
    position: fixed;
    display: none;
    padding: 12px;
    background-color: #fdf9d9;
    border: 2px solid black;
    border-radius: 6px;
}
.base-tooltip__body--active {
    display: block;
}
</style>
